﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using MySql.Data;
using MySql.Data.MySqlClient;
using System.Windows.Forms;

namespace AGPR.Locadora.Data
{
    /// <summary>
    /// Classe de Conexão com o Banco de Dados
    /// 1º Camada - DAL (Data Access Layer)
    /// </summary>
    public class Database
    {
        #region Atributos

        const string HOST = "localhost";
        const string USER = "locadora";
        const string PASS = "locadora";
        const string DATABASE = "locadora";

        /// <summary>
        /// Conexão com o Banco de Dados
        /// </summary>
        private MySqlConnection conn;

        /// <summary>
        /// Conexão Aberta
        /// </summary>
        public bool conectado
        {
            get
            {
                return this.conn.State == ConnectionState.Open;
            }
        }

        /// <summary>
        /// Status da Conexão
        /// </summary>
        public string status
        {
            get
            {
                return this.conn.State.ToString();
            }
        }

        /// <summary>
        /// Descrição do Status
        /// </summary>
        public string statusDesc;

        #endregion

        #region Instancia > Singleton

        /// <summary>
        /// Singleton
        /// </summary>
        private static Database instancia;

        /// <summary>
        /// Retorna a Instancia da Classe Database
        /// </summary>
        public static Database Instancia
        {
            get
            {
                if (instancia == null)
                {
                    instancia = new Database();
                }

                return instancia;
            }
        }

        #endregion

        #region ~Construtor

        /// <summary>
        /// Construtor que instancia a conexão
        /// </summary>
        public Database()
        {
            this.conn = new MySqlConnection(this.getConnString());
        }

        #endregion

        #region getConnString > Retorna a string de Conexão com o banco de dados
        /// <summary>
        /// Retorna a string de Conexão com o banco de dados
        /// </summary>
        /// <returns>String de Conexão</returns>
        private string getConnString()
        {
            string conn =
                "SERVER=" + HOST + ";DATABASE=" + DATABASE + ";UID=" + USER + ";PASSWORD=" + PASS + ";Allow Zero Datetime=true;";

            return conn;
        }
        #endregion

        #region conectar > Conectar ao Banco de dados
        /// <summary>
        /// Abre conexão com o Banco de dados
        /// </summary>
        /// <returns>TRUE ou FALSE</returns>
        public bool conectar()
        {
            if ( ! this.conectado)
            {
                try
                {
                    this.conn.Open();
                    this.statusDesc = "Conectado com Sucesso!";
                }
                catch (MySqlException ex)
                {
                    this.statusDesc = "Erro ao se conectar ao banco de dados: #" + ex.Number;

                    switch (ex.Number)
                    {
                        case 0:
                            this.statusDesc = "Error ao se conectar ao Servidor";
                            break;

                        case 1045:
                            this.statusDesc = "Usuário ou Senha Inválido";
                            break;
                    }

                    MessageBox.Show("Mensagem do Banco de Dados: \n" + this.statusDesc);
                }

            }

            return this.conectado;
        }
        #endregion

        #region desconectar > Desconectar do Banco de dados
        /// <summary>
        /// Fecha conexão com o banco de dados
        /// </summary>
        /// <returns>TRUE ou FALSE</returns>
        public bool desconectar()
        {
            try
            {
                this.conn.Close();
                return true;
            }
            catch (MySqlException ex)
            {
                MessageBox.Show(ex.Message);
                return false;
            }
        }
        #endregion

        #region query > Executa uma query

        /// <summary>
        /// Executa a query e retorna um Comando MySql
        /// </summary>
        /// <param name="query">Query a ser executada</param>
        /// <returns>Comando MySQL</returns>
        public MySqlCommand query(string query)
        {
            return new MySqlCommand(query, this.conn);
        }

        /// <summary>
        /// Executa a query e retorna um DataAdaper
        /// </summary>
        /// <param name="query">Query a ser executada</param>
        /// <returns>DataAdaper</returns>
        public MySqlDataAdapter queryAdapter(string query)
        {
            return new MySqlDataAdapter(query, this.conn);
        }

        /// <summary>
        /// Executa a query e retorna um DataSet
        /// </summary>
        /// <param name="query">Query a ser executada</param>
        /// <returns>DataSet</returns>
        public DataSet queryDataSet(string query)
        {
            DataSet ds = new DataSet();
            MySqlDataAdapter adapter = this.queryAdapter(query);

            adapter.Fill(ds);

            return ds;
        }

        /// <summary>
        /// Executa a query e retorna um DataTable
        /// </summary>
        /// <param name="query">Query a ser executada</param>
        /// <returns>DataTable</returns>
        public DataTable queryTable(string query)
        {
            DataTable table = new DataTable();
            MySqlDataAdapter adapter = this.queryAdapter(query);

            adapter.Fill(table);

            return table;
        }

        #endregion

        #region ~Destructor

        /// <summary>
        /// Desconecta ao fim do uso da classe
        /// </summary>
        ~Database()
        {
            this.desconectar();
        }

        #endregion
    }
}
